/**   
* @Title: WechatServiceImpl.java 
* @Package com.leesche.zcsp.node.pay.wecha.service.encha.impl 
* @Description:() 
* @author dennies yang
* @date 2016年10月9日 下午7:35:38 
* @version V1.0   
*/
package com.leesche.zcsp.node.pay.wecha.service.encha.impl;

import com.leesche.zcsp.node.pay.wecha.data.*;
import com.leesche.zcsp.node.pay.wecha.service.WechatService;
import com.leesche.zcsp.node.pay.wecha.timer.WechatTimer;
import com.leesche.zcsp.node.pay.wecha.utils.SignUtil;
import com.leesche.zcsp.node.pay.wecha.utils.Signature;
import com.leesche.zcsp.node.pay.wecha.utils.XMLUtil;
import com.leesche.zcsp.node.utils.GetWxOrderno;
import com.leesche.zcsp.node.utils.HttpUtil;
import com.leesche.zcsp.node.utils.PayConfig;
import com.leesche.zcsp.node.utils.RequestHandler;
import com.leesche.zcsp.node.web.model.ServOrder;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * @Title: WechatServiceImpl.java
 * @Package com.leesche.zcsp.node.pay.wecha.service.encha.impl
 * @Description:()
 * @author dennies yang
 * @date 2016年10月9日 下午7:35:38
 * @version V1.0
 */
@SuppressWarnings("all")
@Service("wechatService")
public class WechatServiceImpl implements WechatService {
	private final static Logger LOGGER = Logger.getLogger(WechatServiceImpl.class);

	@Override
	public Message<Oauth2To> getOauth(String code) {
		String Oauth2Url = PayConfig.WECHAT_OAUTH.replace("APPID", PayConfig.appid)
				.replace("SECRET", PayConfig.appsecret).replace("CODE", code);
		System.out.println("Oauth2Url:"+Oauth2Url);

		String result = HttpUtil.get(Oauth2Url, null);

		LOGGER.error(result);
		System.out.println("result:"+result);
		return Message.wechatMessage(result, Oauth2To.class);
	}

	@Override
	public String getWechatRedirectUrl(String url) {
		return PayConfig.WECHAT_OAUTHVIEW.replace("APPID", PayConfig.appid).replace("REDIRECT_URI", url);
	}

	@Override
	public String getWechatRedirectUrlSino(String url) {
		return PayConfig.WECHAT_OAUTHVIEW.replace("APPID", PayConfig.SINOPAY_APPID_TEST).replace("REDIRECT_URI", url);
	}

	@Override
	public Message<String> prePay(ServOrder order, String ip, String openid,String tradeType) {
		String prepay_Id;
		PayInfo payInfo = createPayInfo(order, ip, openid, "",tradeType);
		try {
			payInfo.setSign(Signature.getSign(payInfo));
			StringBuffer sb = new StringBuffer();
			sb.append("<xml>");
			sb.append("<appid>" + payInfo.getAppid() + "</appid>");
//			sb.append("<service>" + PayConfig.SINOPAY_PREPAY_SERVICE + "</service>");
			sb.append("<mch_id>" + payInfo.getMch_id() + "</mch_id>");
			sb.append("<device_info>" + payInfo.getDevice_info() + "</device_info>");
			sb.append("<nonce_str>" + payInfo.getNonce_str() + "</nonce_str>");
			sb.append("<sign>" + payInfo.getSign() + "</sign>");
			sb.append("<body>" + payInfo.getBody() + "</body>");
			sb.append("<attach>" + payInfo.getAttach() + "</attach>");
			sb.append("<out_trade_no>" + payInfo.getOut_trade_no() + "</out_trade_no>");
			sb.append("<total_fee>" + payInfo.getTotal_fee() + "</total_fee>");
			sb.append("<spbill_create_ip>" + payInfo.getSpbill_create_ip() + "</spbill_create_ip>");
			sb.append("<notify_url>" + payInfo.getNotify_url() + "</notify_url>");
			sb.append("<trade_type>" + payInfo.getTrade_type() + "</trade_type>");
			sb.append("<openid>" + payInfo.getOpenid() + "</openid>");
			sb.append("</xml>");
//			System.out.println(sb.toString());
			LOGGER.info("request xml string:" + sb.toString());
			String result = HttpUtil.post(PayConfig.WECHAT_UNIFIEORDER, sb.toString(), HttpUtil.getPostHeaders());
//			String result = HttpUtil.post2(PayConfig.SINOPAY_URL_TEST, sb.toString(), HttpUtil.getPostHeaders());
//			LOGGER.info("sinopay prepay result:" + result);
//			System.out.println(result);
			Map<String, String> map = XMLUtil.parseXml(result);
			String return_code = map.get("return_code");
			if (StringUtils.isNotBlank(return_code) && return_code.equals("SUCCESS")) {
				String return_msg = map.get("return_msg");
				if (StringUtils.isNotBlank(return_msg) && !return_msg.equals("OK")) {
					return Message.error("下单失败!", new Object[0]);
				}
			} else {
				return Message.error("下单失败!", new Object[0]);
			}
			prepay_Id = map.get("prepay_id");
		} catch (Exception e) {
			return Message.error("下单失败!", new Object[0]);
		}

		return Message.success(prepay_Id, new Object[0]);
	}

	/**
	 * 创建统一下单的xml的java对象
	 * 
	 * @param bizOrder
	 *            系统中的业务单号
	 * @param ip
	 *            用户的ip地址
	 * @param openId
	 *            用户的openId
	 * @return
	 */
	private PayInfo createPayInfo(ServOrder order, String ip, String openId, String url,String tradeType) {
		PayInfo payInfo = new PayInfo();
		payInfo.setAppid(PayConfig.appid);
		payInfo.setDevice_info("WEB");
		payInfo.setMch_id(PayConfig.partner);//PayConfig.partner  SINOPAY_MCHID_TEST
		payInfo.setNonce_str(SignUtil.getRandomStringByLength(32));
		String body = (order.getCashFee()/100) + "元" + order.getCoin() + "币";
		payInfo.setBody(body);
		payInfo.setAttach("" + (order.getCashFee() * 100));
		payInfo.setOut_trade_no(order.getOutTradeNo());
		System.out.println(" prepay sn:" + order.getOutTradeNo());
//		payInfo.setTotal_fee((order.getCashFee() * 100));
		payInfo.setTotal_fee(1);
		payInfo.setSpbill_create_ip(ip);
		payInfo.setNotify_url(PayConfig.WECHAT_NOTIFY_URL);
		payInfo.setTrade_type(tradeType);
		payInfo.setOpenid(openId);
		return payInfo;
	}

	@Override
	public Message<String> WechatNotify(XmlParam xmlParam) {
		return null;
	}
	@Override
	public XmlParam onScan(String nonceStr, Message<String> message,String encode) {
		RequestHandler reqHandler = new RequestHandler(encode);
		reqHandler.init(PayConfig.appid, PayConfig.appsecret,
				PayConfig.partnerkey);
		XmlParam param = new XmlParam(reqHandler);
		param.putParam("appid", PayConfig.appid);
		param.putParam("mch_id", PayConfig.partner);
		param.putParam("nonce_str", nonceStr);
		param.putParam("prepay_id", message.getContent());
		if(message.getType()==Message.Type.success){
			param.putParam("return_code", "SUCCESS");
			param.putParam("result_code", "SUCCESS"); 
		}else {
			param.putParam("err_code_des", "支付失败!");
			param.putParam("return_code", "FAIL");
			param.putParam("result_code", "FAIL"); 
		}
		System.out.println("param:"+param.toString());
		return param;
	}

	@Override
	public Message<AccessToken> getWechatAccessToken() {
		String  accessTokenURL=PayConfig.WECHAT_ACCESS_TOKEN.replace("APPID", PayConfig.appid).replaceAll("APPSECRET", PayConfig.appsecret);
		String result = HttpUtil.get(accessTokenURL, null);
		LOGGER.error(result);
		return Message.wechatMessage(result, AccessToken.class);	}

	@Override
	public Message<WechatJsToken> getWechatJsToken(String accessToken) {
		String jsTokenURL=PayConfig.WECHAT_JS_TOKEN.replace("ACCESS_TOKEN", accessToken);
		String result = HttpUtil.get(jsTokenURL, null);
		LOGGER.error(result);
		return Message.wechatMessage(result, WechatJsToken.class);
	}

	@Override
	public Message<AccessToken> refreshWechatAccessToken() {
		Message<AccessToken> am=this.getWechatAccessToken();
		if(Message.isSuccess(am.getType())){
			 WechatTimer.ASSCEE_TOKEN=am.getContent().getAccess_token();
		}else if(Message.isError(am.getType())){
			LOGGER.error(am);
		}
	
		
		return am;
	}

	@Override
	public Message<WechatJsToken> refreshWechatJsToken() {
		if(StringUtils.isBlank(WechatTimer.ASSCEE_TOKEN)){
			refreshWechatAccessToken();
		}		
		Message<WechatJsToken> jm=this.getWechatJsToken(WechatTimer.ASSCEE_TOKEN);
		if(Message.isSuccess(jm.getType())){
			 WechatTimer.JS_TIKET=jm.getContent().getTicket();
		}else if(Message.isError(jm.getType())){
			LOGGER.error(jm);
		}
		return jm;
	}

	@Override
	public Message<String> wechattransfers(String ip, String openid, int money,String desc ,String encode,String orderNo) {
		RequestHandler reqHandler = new RequestHandler(encode);
		reqHandler.init(PayConfig.appid, PayConfig.appsecret,PayConfig.partnerkey);
		XmlParam param = new XmlParam(reqHandler);
		param.putParam("amount", String.valueOf(money));
		param.putParam("check_name", PayConfig.WECHAT_TRANSFERS_NO_CHECK);
		param.putParam("desc", desc);
		param.putParam("mch_appid", PayConfig.appid);
		param.putParam("mchid", PayConfig.partner);
		param.putParam("nonce_str", SignUtil.getRandomStringByLength(32));
		param.putParam("openid", openid);
		param.putParam("partner_trade_no", orderNo);
		param.putParam("spbill_create_ip", ip);
		String xmlStr;
		try {
			xmlStr = GetWxOrderno.callXml(PayConfig.transfers, param.toString());
			Map<String, String> map = GetWxOrderno.doXMLParse(xmlStr);
			LOGGER.info("提现返回：" + xmlStr);
			String res = map.get("result_code");
			if (res.equals("SUCCESS")) {
				LOGGER.info("提现成功");
				/*String partner_trade_no1 = map.get("partner_trade_no ");
				String openid1 = map.get("openid");
				String payment_amount1 = map.get("payment_amount");
				String mch_id1 = map.get("mch_id");*/
				return Message.success(orderNo, null);
				
			} else {
				LOGGER.info("提现失败, 失败原因:" + map.get("err_code_des"));
				return Message.error("提现失败 :"+map.get("err_code_des"), null);
			}
		} catch (Exception e) {
			return Message.error("提现失败 :"+e.toString(), null);

		}
	}
	
	
	
	
	
	
	

}
